#include "sysapi.h"
#include <stdio.h>
#include <time.h>
#include <assert.h>

#if defined(_WIN64) || defined(_WIN64)
#include "wdm.h"
#endif  // _WIN64

unsigned long long KstlSteadyTimeNano()
{
#define NONOSECONDS_IN_CLOCK_TICK 100
#if defined(_WIN64) || defined(_WIN64)
#ifdef TESTING
    time_t time = clock();
    return (unsigned long long)(((double)time / CLOCKS_PER_SEC) * 10e9);
#else
    LARGE_INTEGER count;
    KeQueryTickCount(&count);
    return count.QuadPart * KeQueryTimeIncrement() * NONOSECONDS_IN_CLOCK_TICK;
#endif
#else
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (unsigned long long)ts.tv_sec * 1000000000ULL + (unsigned long long)ts.tv_nsec;
#endif
#undef NONOSECONDS_IN_CLOCK_TICK
}

void* KstlAllocate(size_t size)
{
#ifdef TESTING
    return malloc(size);
#else
    return ExAllocatePool2(POOL_FLAG_NON_PAGED, size, 'KSTL');
#endif
}

void KstlRelease(void* handle)
{
#ifdef TESTING
    free(handle);
#else
    ExFreePool(handle);
#endif
}